<script setup>
import headers from '~/src/components/headers.vue';
import useDataStore from '@/store/index.js'
import { nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { getFaceAPI } from '@/apis/chat'
import { storeToRefs } from 'pinia';
import { sfm } from '~/src/utils/tool';
// import IScroll from '~/build/iscroll';
import IScroll from 'iscroll';
import Compressor from 'compressorjs';

defineOptions({
    name: 'Rate'
})

//动态导入模块
// 匹配正则下的所有文件，{ eager: false }不要立即加载
// const images = import.meta.glob('@/assets/images/face/*.png', { eager: false });
// console.log('images', images);


/* -------------------------------- 获取用户个人信息 -------------------------------- */
const dataStore = useDataStore()
const { userInfo, isMobile } = storeToRefs(dataStore)

const WEB_SOCKET = import.meta.env.VITE_WEB_SOCKET  //websocket地址

/* ------------------------- 页面加载完后自动连接websocket服务器 ------------------------- */
let messageList = ref([])   //信息数组，用于渲染页面
let socket = null       // socket对象
let messageValue = ref()    // 用户输入的将要发送的内容
let clients = ref([])     // 当前在线的用户对象数组
let faceList = ref([])  //表情列表
let fileList = ref([])  //文件列表
let mentionOptions = ref([
    { value: 'DeepSeek', label: 'DeepSeek' },
])   //@列表
let callDSStatus = ref(false)  //是否开启DeepSeek

// for (const path in images) {
//     faceList.value.push({
//         id: path.substring(24).slice(0, -4),
//         path
//     });
// }
// console.log(faceList.value);


onMounted(() => {
    socketAction()
    getFace()
})

//当页面组件销毁前关闭socket连接 并释放临时url
onBeforeUnmount(() => {
    messageSend({
        type: 'close',
        nickname: userInfo.value.user_name
    })
    clearBlobUrl()
    socket.close()
})

// 二次封装socket的send方法，使send可以发送对象
const messageSend = (data) => {
    // 把要发送的对象转为json字符串的形式，服务器再进行解析
    socket.send(JSON.stringify(data))
    messageValue.value = ''
}

const socketAction = () => {
    console.log(WEB_SOCKET);
    socket = new WebSocket(WEB_SOCKET)
    socket.onopen = () => {
        console.log('开始建立连接');
        messageSend({
            type: 'login',
            nickname: userInfo.value.user_name,
            avatar: userInfo.value.user_avatar,
        })
    }
    socket.onerror = (err) => {
        console.log('连接错误', err);
    }
    socket.onmessage = (data) => {
        const message = JSON.parse(data.data)
        console.log('接收信息', message);

        let shouldPush = true;  // 是否应该将消息添加到消息列表中

        if (message.type === 'clients') {   // 是用户进入/离开聊天室类型的信息时
            console.log('arr', Array.from(message.clients));
            clients.value = Array.from(message.clients)
        } else {
            if (message.isMedia === 'file') {
                let text = message.text
                console.log('stream', message);

                // const reader = new FileReader()
                // reader.onload = (event) => {
                //     message.text = event.target.result
                // }
                // reader.readAsDataURL(text)
                // const blob = new Blob([text], { type: 'application/octet-stream' })
                // const url = URL.createObjectURL(blob)
                // message.text = url
            }
            messageList.value.forEach(item => {
                if (item.messageId && item.messageId === message.messageId && item.status === 'thinking') {
                    item.text = message.text
                    item.status = 'answered'
                    shouldPush = false
                }
            })
            if (shouldPush) {
                messageList.value.push(message)
            }
        }
        console.log(clients.value);
    }
    socket.onclose = () => {
        console.log('断开连接 ');
    }
}


/* ------------------------------ 让聊天面板始终滚动到最底部 ----------------------------- */
let panelBoxRef = ref() // 外层滚动容器
let panelRef = ref()    // 内层滚动元素
let scroll = ref()      // scroll 对象
// 配置并创建滚动对象
onMounted(() => {
    // scroll.value = new IScroll(panelBoxRef.value, {
    //     scrollY: true,  // y轴滚动
    //     bounce: true,   // 是否到达边界具有反弹效果
    //     mouseWheel: true,   // 鼠标滚轮滚动
    //     scrollbars: false,  // 是否显示滚动条
    //     tap: true,
    //     click: true,
    //     // tap: true,

    // })
})
// 当消息数组发生变化，刷新滚动视图
watch(messageList.value, () => {
    setTimeout(() => {
        console.log(panelRef.value.offsetHeight, panelBoxRef.value.offsetHeight);
        // scroll.value.refresh()
        if (panelRef.value.offsetHeight > panelBoxRef.value.offsetHeight) {
            // scroll.value.scrollTo(0, panelBoxRef.value.offsetHeight - panelRef.value.offsetHeight, 500)
            // panelBoxRef.value.scrollTop = panelRef.value.offsetHeight

            panelBoxRef.value.scrollTo({
                top: panelRef.value.offsetHeight,
                left: 0,
                behavior: 'smooth'
            })
        }

    })
}, {
    flush: "post"
})


// 点击发送
const sendAction = (data) => {
    if (!data.text) {
        ElMessage({
            type: 'warning',
            message: '不能发送空内容'
        })
        return
    }
    if (callDSStatus.value) {
        data.text = '@DeepSeek ' + data.text
    }
    messageSend(data)
}

//释放blob url
const clearBlobUrl = () => {
    console.log('clear url');
    messageList.value.forEach(item => {
        if (item.isMedia === 'file') {
            // URL.revokeObjectURL(item.text)
            item.text = ''
        }
    })
}



// 发送表情
const sendFace = (name) => {
    let faceFileItem = faceList.value.find(item => item.face_name === name)
    console.log(faceFileItem);
    messageSend({
        type: 'face',
        nickname: userInfo.value.user_name,
        text: faceFileItem.face_path
    })
}

// 获取表情
const getFace = async () => {
    let res = await getFaceAPI()
    if (res.code === 200) {
        faceList.value = res.data
    }
}

// 选择图片
const imageBeforeUpload = (file) => {
    if (file.status === 'ready') {
        if (file.size / 1024 / 1024 < 2) {
            let extList = ['jpg', 'jpeg', 'png', 'gif']
            let pattern = /\.([a-zA-Z0-9]+)$/
            let match = file.name.match(pattern)
            if (extList.includes(match[1])) {

                // 压缩文件
                new Compressor(file.raw, {
                    quality: 0.6,
                    success: (result) => {
                        const reader = new FileReader()
                        reader.onload = (event) => {
                            const arrayBuffer = event.target.result
                            // console.log('base', arrayBuffer);
                            messageSend({
                                type: 'file',
                                nickname: userInfo.value.user_name,
                                text: arrayBuffer
                            })
                            // socket.send(arrayBuffer)
                        }
                        reader.readAsDataURL(result)
                    }
                })
            } else {
                ElMessage({
                    type: 'warning',
                    message: '只能选择图片'
                })
                return
            }
        } else {
            ElMessage({
                type: 'warning',
                message: '文件过大，请重新选择'
            })
            return
        }
    }

}

// 召唤ds
const callDS = () => {
    callDSStatus.value = !callDSStatus.value
}

</script>

<template>
    <div class="page">
        <div class="container">
            <!-- <div class="headers">
                <headers :userInfo="userInfo"></headers>
            </div> -->
            <div class="temp" v-show="!isMobile"></div>
            <div class="main">
                <div class="left">
                    <div class="panelRef" ref="panelBoxRef">

                        <div class="panel" ref="panelRef">
                            <div class="item" v-for="item in messageList" :key="new Date().getTime()">
                                <div v-if="item.type === 'login-success'" class="tips">欢迎你，{{ item.name }}</div>
                                <div v-else-if="item.type === 'user-join'" class="tips">{{ item.name }}进入了聊天室</div>
                                <div v-else-if="item.type === 'other-close'" class="tips">{{ item.name }}离开了聊天室</div>
                                <div v-else-if="item.type === 'other-send'" class="panel-user-left">
                                    <div class="user-info">
                                        <div class="user-avatar"><img :src="item.avatar" alt=""></div>
                                        <div class="user-name">
                                            <div>{{ item.name }}</div>
                                            <div class="name-title" v-if="item.name === 'DeepSeek'">AI助手</div>
                                        </div>
                                    </div>
                                    <div class="user-face" v-if="item.isMedia"><img :src="item.text" alt=""></div>
                                    <!-- <div class="user-text" v-if="item.status === 'thinking'" v-loading>{{  }}</div> -->
                                    <div :class="{ 'user-text': true, 'user-text-loading': item.status === 'thinking' }"
                                        v-else v-loading="item.status === 'thinking'" :element-loading-text="item.text">
                                        {{ item.status === 'thinking' ? '' : item.text }}
                                    </div>
                                    <div class="user-time">{{ item.time }}</div>
                                </div>
                                <div v-else-if="item.type === 'me-send'" class="panel-user-right">
                                    <div class="user-info">
                                        <div class="user-name">
                                            <div>{{ item.name }}</div>
                                        </div>
                                        <div class="user-avatar"><img :src="item.avatar" alt=""></div>
                                    </div>
                                    <div class="user-face" v-if="item.isMedia">
                                        <img :src="item.text" alt="">
                                    </div>
                                    <div class="user-text" v-else>{{ item.text }}</div>
                                    <div class="user-time">{{ item.time }}</div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <div class="area">
                        <div class="area-tool">
                            <el-popover :width="300" :show-arrow="false" placement="top-start"
                                :trigger="isMobile ? 'click' : 'hover'"
                                popper-style="box-shadow: rgb(14 18 22 / 35%) 0px 10px 38px -10px, rgb(14 18 22 / 20%) 0px 10px 20px -15px; padding: 20px;">
                                <template #reference>
                                    <div class="tool-item" @click="selectImage">
                                        <i class="iconfont icon-biaoqing"></i>
                                    </div>
                                </template>
                                <template #default>
                                    <div class="face">
                                        <div class="face-item" v-for="item in faceList" :key="item.face_id"
                                            @click="sendFace(item.face_name)">
                                            <img v-lazy="item.face_path" alt="">
                                        </div>
                                    </div>
                                </template>
                            </el-popover>
                            <div class="tool-item">
                                <el-tooltip class="box-item" effect="dark" content="发送图片" placement="top-start">
                                    <el-upload v-model:file-list="fileList" style="display: flex; align-items: center;"
                                        :show-file-list="false" :auto-upload="false" :on-change="imageBeforeUpload">
                                        <i class="iconfont icon-icon1"></i>
                                    </el-upload>
                                </el-tooltip>
                            </div>
                            <div class="tool-item" style="cursor: pointer;" @click="callDS">
                                <el-tooltip class="box-item" effect="dark" content="召唤AI" placement="top-start">
                                    <i :style="{ color: callDSStatus ? '#626aef' : '' }"
                                        class="iconfont icon-airbnb"></i>
                                </el-tooltip>
                            </div>
                            <div class="btn">
                                <el-button color="#626aef"
                                    @click="sendAction({ type: callDSStatus ? 'callDS' : 'send', nickname: userInfo.user_name, text: messageValue })">{{
                                        callDSStatus ? '@DeepSeek ' : '发送' }}</el-button>
                            </div>
                        </div>
                        <div class="area-text">
                            <el-input type="textarea" v-model="messageValue" style="width: 100%; border: none;" rows="4"
                                placeholder="在这里输入信息...">
                            </el-input>
                            <!-- <el-mention v-model="messageValue" whole type="textarea" :options="mentionOptions"
                                style="width: 100%;border: none;" rows="4" placeholder="在这里输入信息..." /> -->
                        </div>
                    </div>
                </div>
                <div class="right">
                    <div class="right-top">
                        <div class="top-title">当前频道在线人数</div>
                        <div class="top-num">{{ clients.length + 100 }}</div>
                    </div>
                    <!-- <div class="right-middle">
                        <div class=""></div>
                    </div> -->
                    <div class="right-bottom" v-show="!isMobile">
                        <div class="bottom-title">当前在线用户</div>
                        <div class="bottom-group">

                            <div class="group-item" v-for="item in clients" :key="item">
                                <div class="item-avatar"><img :src="item.avatar" alt=""></div>
                                <div class="item-name">{{ item.nickname }}</div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<style lang="scss" scoped>
@import url(./rate.scss);
</style>